#include "debug.h"
#include "../DDIC/AllDDIC.h"
#include "usbd_cdc.h"
#include "../DEMURA/Demura.h"

void WD6300_670_Demura_Readback_Check(u8 SigMode ,u8 channel, u8 reg, u8 readbackNum){
	u16 tmp = 0;
	u8 buffer1[2];
	u8 Rxbuffer[9];

	SSD2828_W_Reg(SigMode, channel, 0xB7, LP_DCS_Long_Read);
	while(1){		
		SSD2828_W_Reg(SigMode, channel, 0xC1, 0x0008); //return package 
		SSD2828_W_Reg(SigMode, channel, 0xC0, 0x0001); //reset
		buffer1[0] = 0x01;
		buffer1[1] = reg; 	//Download register
		SSD2828_W_Array(SigMode, channel, buffer1, 0);
		delay_ms(5); 

		SSD2828_W_Reg(SigMode, channel,0xD4,0x00FA);
		SSD2828_W_Cmd(SigMode, channel,0xFF);
		for(i = 0; i < readbackNum; i++)  //readback num
		{
			SSD2828_W_Cmd(SigMode, channel, 0xFA);
			tmp = SPI3_Read_u16_Data(channel);
			Rxbuffer[i] = tmp >> 8;
			Rxbuffer[1 + i]= tmp;
			delay_ms(5);
			i++;
		}
		
		if(Rxbuffer[4] == 0x01){
			SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
			delay_ms(10);
			return;
		}			
	}
}

void WD6300_670_Demura_Enable_Flash_Control_and_SPI_Flash_En(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
	
}

void WD6300_670_Demura_Inter_Demura_Ram(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
	SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
	delay_ms(10);
    //step1
    u8 buffer13[] = {0x05,0xD0,0x5A,0xA5,0x11,0x00};
    u8 buffer14[] = {0x0A,0x7A,0x0D,0x00,0x43,0x02,0x0C,0x0C,0x00,0x80,0x00};
    u8 buffer15[] = {0x05,0xD0,0x5A,0xA5,0x11,0x04};
    u8 buffer16[] = {0x05,0xD0,0x5A,0xA5,0x11,0x25};
    u8 buffer17[] = {0x02,0x60,0x01};
    u8 buffer18[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer19[] = {0x05,0xD0,0x5A,0xA5,0x11,0x00};
    u8 buffer20[] = {0x03,0x7A,0x0D,0x00};
    u8 buffer21[] = {0x04,0xD1,0xB4,0x69,0x11};    
    u8 buffer22[] = {0x05,0xD4,0x5A,0xA5,0x11,0x11}; 
    u8 buffer23[] = {0x05,0xD0,0x5A,0xA5,0x11,0x23};    
    u8 buffer24[] = {0x02,0x65,0x03};
    u8 buffer25[] = {0x02,0x65,0x00};    
    u8 buffer26[] = {0x05,0xD0,0x5A,0xA5,0x11,0x22};        
    u8 buffer27[] = {0x02,0x60,0x01};            
	SSD2828_W_Array(SigMode,channel,buffer13,0);
	SSD2828_W_Array(SigMode,channel,buffer14,0);
    SSD2828_W_Array(SigMode,channel,buffer15,0);
	SSD2828_W_Array(SigMode,channel,buffer16,0);
	SSD2828_W_Array(SigMode,channel,buffer17,0);
    SSD2828_W_Array(SigMode,channel,buffer18,0);
	SSD2828_W_Array(SigMode,channel,buffer19,0);
	SSD2828_W_Array(SigMode,channel,buffer20,0);
    SSD2828_W_Array(SigMode,channel,buffer21,0);
	SSD2828_W_Array(SigMode,channel,buffer22,0);
	SSD2828_W_Array(SigMode,channel,buffer23,0);
    SSD2828_W_Array(SigMode,channel,buffer24,0);
	SSD2828_W_Array(SigMode,channel,buffer25,0);
	SSD2828_W_Array(SigMode,channel,buffer26,0);
    SSD2828_W_Array(SigMode,channel,buffer27,0);
    delay_ms(50);
    SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
	delay_ms(1000);
    buffer[0] = 0x2F;
    buffer[1] = 0x01;		

    SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
    STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3);  
}
                                    
void WD6300_670_Demura_Exit_Demura_Ram(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    
}
                             
void WD6300_670_Demura_Flash_Write_Demura(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    
}                       

void WD6300_670_Demura_Flash_Check_Demura(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
	delay_ms(10);
    //*enable dmsram lut read write*/
    u8 buffer1[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer2[] = {0x05,0xD4,0x5A,0xA5,0x00,0x00};
    u8 buffer3[] = {0x05,0xD0,0x5A,0xA5,0x11,0x22};
	SSD2828_W_Array(SigMode,channel,buffer1,0);
	SSD2828_W_Array(SigMode,channel,buffer2,0);
    delay_ms(10);
    SSD2828_W_Array(SigMode,channel,buffer3,0);
    
    //flash bus sel to flash burner
    u8 buffer4[] = {0x02,0x60,0x01};    
    //rif_fbl_demu_init_en
    u8 buffer5[] = {0x02,0x63,0x01};    
    //lut initial 0x4650
    u8 buffer6[] = {0x05,0xD0,0x5A,0xA5,0x11,0x23};
    u8 buffer7[] = {0x02,0x65,0x03};
    u8 buffer8[] = {0x02,0x65,0x00};    
    //*flash clk div, port switch to dm-sram, address_inc off*/
    u8 buffer9[] = {0x05,0xD0,0x5A,0xA5,0x11,0x21};
    u8 buffer10[] = {0x08,0x62,0x02,0x44,0x40,0x00,0xff,0x06,0x05};    
    //60,02,0xAddr_H,0xAddr_M,0xAddr_L,0xPageSize_H,0xPageSize_L,FF,FF,7E,01
    u8 buffer11[] = {0x0B,0x60,0x02,0x01,0x70,0x00,0x14,0xA2,0xFF,0xFF,0x7E,0x01};    
	SSD2828_W_Array(SigMode,channel,buffer4,0);
	SSD2828_W_Array(SigMode,channel,buffer5,0);
    SSD2828_W_Array(SigMode,channel,buffer6,0);
	SSD2828_W_Array(SigMode,channel,buffer7,0);
	SSD2828_W_Array(SigMode,channel,buffer8,0);
    SSD2828_W_Array(SigMode,channel,buffer9,0);
	SSD2828_W_Array(SigMode,channel,buffer10,0);
	SSD2828_W_Array(SigMode,channel,buffer11,0);
	
	//check finish
	WD6300_670_Demura_Readback_Check(SigMode, channel, 0x61, 0x08);
    //delay_ms(10000);
    
    //system reset
//    u8 buffer12[] = {0x05,0xD0,0x5A,0xA5,0x11,0x25};
//    u8 buffer13[] = {0x02,0x60,0x01};
//    u8 buffer14[] = {0x04,0xD1,0xB4,0x69,0x11};
//    u8 buffer15[] = {0x05,0xD0,0x5A,0xA5,0x11,0x00};
//    u8 buffer16[] = {0x03,0x7A,0x0D,0x00};    
//    SSD2828_W_Array(SigMode,channel,buffer12,0);
//	SSD2828_W_Array(SigMode,channel,buffer13,0);
//	SSD2828_W_Array(SigMode,channel,buffer14,0);
//	SSD2828_W_Array(SigMode,channel,buffer15,0);
//	SSD2828_W_Array(SigMode,channel,buffer16,0);
	
    buffer[0] = 0x2F;
    buffer[1] = 0x03;

    SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
    STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3);        
}
                                  
void WD6300_670_Demura_Flash_Erase_Demura(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{	
    SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
	delay_ms(10);
	
	//28
	u8 buffer12[] = {0x01,0x28};
	SSD2828_W_Array(SigMode, channel, buffer12, 0);
	delay_ms(10);
	
	//ELVDD and ELVSS off
	u8 buffer13[] = {0x06,0xFF,0xFF,0xFC,0x66,0x00,0x02};
	SSD2828_W_Array(SigMode, channel, buffer13, 0);
	delay_ms(10);

    u8 buffer1[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer2[] = {0x05,0xD0,0x5A,0xA5,0x11,0x22};
    u8 buffer3[] = {0x02,0x60,0x01};
	SSD2828_W_Array(SigMode, channel, buffer1, 0);
	SSD2828_W_Array(SigMode, channel, buffer2, 0);
    SSD2828_W_Array(SigMode, channel, buffer3, 0);
    delay_ms(10);
    
    u8 buffer11[] = {0x05,0xD0,0x5A,0xA5,0x11,0x21};
    SSD2828_W_Array(SigMode, channel, buffer11, 0);
    //sector erase
    //4k 
    u8 buffer4[12] = {0x0B,0x60,0x20,0x01,0x70,0x00,0x00,0x00,0x00,0xFF,0x75,0x01};
    SSD2828_W_Array(SigMode, channel, buffer4, 0);
	delay_ms(50);
    //delay_ms(1000);
	//check finish
	WD6300_670_Demura_Readback_Check(SigMode, channel, 0x61, 0x08);
    
    //32k
    buffer4[2] = 0x52;
    buffer4[4] = 0x80;
    SSD2828_W_Array(SigMode, channel, buffer4, 0);
	delay_ms(50);
    //delay_ms(1000);
	//check finish
	WD6300_670_Demura_Readback_Check(SigMode, channel, 0x61, 0x08);
    
    //64k
    buffer4[2] = 0xD8;
    buffer4[3] = 0x02;
    buffer4[4] = 0x00;
	//erase 0x020000-0x160000
	for(int z = 0; z < 21; z++){
		SSD2828_W_Array(SigMode, channel, buffer4, 0);
		delay_ms(50);
		//check finish
		WD6300_670_Demura_Readback_Check(SigMode, channel, 0x61, 0x08);
		buffer4[3]++;
	}
       
    u8 buffer5[] = {0x05,0xD0,0x5A,0xA5,0x11,0x25};
    u8 buffer6[] = {0x02,0x60,0x01};
    SSD2828_W_Array(SigMode, channel, buffer5, 0);    
    SSD2828_W_Array(SigMode, channel, buffer6, 0);   

    u8 buffer7[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer8[] = {0x05,0xD4,0x5A,0xA5,0x11,0x11};
    u8 buffer9[] = {0x05,0xD0,0x5A,0xA5,0x11,0x07};
    u8 buffer10[] = {0x02,0x61,0x03};
    SSD2828_W_Array(SigMode, channel, buffer7, 0);    
    SSD2828_W_Array(SigMode, channel, buffer8, 0); 
    SSD2828_W_Array(SigMode, channel, buffer9, 0);    
    SSD2828_W_Array(SigMode, channel, buffer10, 0); 
    
    delay_ms(10);
	buffer[0] = 0x2F;
	buffer[1] = 0x05;		
	buffer[4] = 0x80;	
	SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
	STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3); 
}

void WD6300_670_Demura_Flash_Demura_OTP(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    
}

void WD6300_670_Demura_Demura_Function_ON(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
	delay_ms(5);
    
	u8 buffer1[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer2[] = {0x05,0xD0,0x5A,0xA5,0x11,0x01};
    u8 buffer3[] = {0x02,0x61,0x01};
	
	SSD2828_W_Array(SigMode,channel,buffer1,0);
	delay_ms(5);
	SSD2828_W_Array(SigMode,channel,buffer2,0);
	delay_ms(5);
	SSD2828_W_Array(SigMode,channel,buffer3,0);
	delay_ms(5);

	SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
	STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3);
}

void WD6300_670_Demura_Demura_Function_OFF(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{
    SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);
	delay_ms(5);
    
	u8 buffer1[] = {0x04,0xD1,0xB4,0x69,0x11};
    u8 buffer2[] = {0x05,0xD0,0x5A,0xA5,0x11,0x01};
    u8 buffer3[] = {0x02,0x61,0x00};
	
	SSD2828_W_Array(SigMode,channel,buffer1,0);
	delay_ms(5);
	SSD2828_W_Array(SigMode,channel,buffer2,0);
	delay_ms(5);
	SSD2828_W_Array(SigMode,channel,buffer3,0);
	delay_ms(5);
   
	SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
	STM2PC(pdev,CDC_IN_EP,buffer,buffer[2]+3); 
}

void WD6300_670_Demura_Write_Demura_Ram(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8 buffer[],u16 LP_B7_Data,u16 HS_B7_Data)
{
	bool flag = false;
	//send flash bin data to dmsram use 0x48, 0x49 cmd
    u8 buf2PC[10];
	DemuraTransOnce= 240;	
	if(USB_Rx_Demura==0)//?????
	{	
			buffer[1] = 0x48;
			USB_Rx_Demura=1; //?????Demura??????
	}
	else buffer[1] = 0x49;
	buffer[0] = 0xF1;
	for(i=2;i<USB_ReceivedCount+2;i++)
	{
		buffer[i+VCP_Receive_True_num] = USB_Rx_Buffer[i-2];  //
	}
	VCP_Receive_True_num+=USB_ReceivedCount;  //????????
	DemuraRecivedNum+=USB_ReceivedCount;	  //????????
	int a;
	if((VCP_Receive_True_num==DemuraTransOnce)||(DemuraRecivedNum==USB_Rx_Demura_Total_Num)) //?????? 
	{																					
		a=DemuraRecivedNum%240;//??????,????FF		
		if (a!=0 )
		{
			flag = true;
			for(i=0;i<240-a;i++)
			{
				buffer[2+i+a]=0xff;
			}
		}
		SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);	    	
		SSD2828_W_Array(SigMode,channel,buffer,0);
		
		//After the last packet is 240, add two packets, because the SRAM moved to falsh is 256.
		if(flag == true){
			delay_ms(10);
			flag = false;
			for(i=0;i<240 - 2;i++)
			{
				buffer[2+i]=0xff;
			}
			SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);	    	
			SSD2828_W_Array(SigMode,channel,buffer,0);
			delay_ms(10);
			SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Short_Write);	    	
			SSD2828_W_Array(SigMode,channel,buffer,0);
		}
		
		delay_ms(10);
		VCP_Receive_True_num=0;
			
		if(DemuraRecivedNum==USB_Rx_Demura_Total_Num)//????,????
		{
			DemuraRecivedNum=0; //?? ??????
			USB_Rx_Demura=0;	  //?? Demura downloading??
			Demura_START_FLAG=0;//?? ??Demura??????
			STM2PC(pdev,CDC_IN_EP,buf2PC,5+3);           //?????5?byte??
		}
	}
}

void ProcessForDmuR3D( USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8 buffer[],u16 LP_B7_Data,u16 HS_B7_Data)
{	
	switch(USB_Rx_Buffer[1])
	{
		case 0x01:                                      //????
				WD6300_670_Demura_Inter_Demura_Ram(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;	
		case 0x02:                                      //????
				//WD6300_670_Demura_Exit_Demura_Ram(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;						 
		case 0x03:                                      //????
				//WD6300_670_Demura_Flash_Write_Demura(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
				//WD6300_670_Demura_Write_Demura_Ram(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;	
		case 0x04:                                      //????
				WD6300_670_Demura_Flash_Check_Demura(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;												
		case 0x05:                                      //????
				WD6300_670_Demura_Flash_Erase_Demura(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;
		case 0x06:                                      //check flash ID
				//WD6300_670_Demura_Enable_Flash_Control_and_SPI_Flash_En(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;	
		case 0x07:                                      //check flash ID
				WD6300_670_Demura_Demura_Function_ON(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;	
		case 0x08:                                      //check flash ID
				WD6300_670_Demura_Demura_Function_OFF(pdev,CDC_IN_EP,OLED.SigMode ,channel,USB_Rx_Buffer,LP_B7_Data,HS_B7_Data);
		break;													
		default:
			break;												
	}
}
//********************************************************************************************
